from config import API_CONFIG, DEFAULT_THINKING_TYPE
from volcenginesdkarkruntime import Ark  # pip install -U 'volcengine-python-sdk[ark]'
from utils import (get_formatted_prompt, find_most_frequent_vote, extract_number_from_string, extract_kill_from_string,
                   find_most_frequent_kill)
import time
from collections import Counter


class player:
    def __init__(self, role: str, faction: str, name: str, id: int):
        self.history_messages = []
        self.is_alive = True
        self.name = name
        self.role = role
        self.id = id
        self.faction = faction
        # 初始化
        self.client = Ark(
            api_key=API_CONFIG["api_key"],
            timeout=API_CONFIG["timeout"],
        )

        self.prompt = get_formatted_prompt(
            player_name=self.name,
            player_count=8,
            role=self.role
        )

        # 为角色设置系统提示
        self.history_messages.append(
            {
                "role": "system",
                "content": self.prompt
            }
        )

    def add_history_message(self, ai_role, content):
        """将对话加入历史记忆中"""
        self.history_messages.append(
            {"role": ai_role, "content": content}
        )

    def get_response(self, user_input, thinking_type="disabled"):
        """获取模型回复,并加入到历史记忆中"""
        self.add_history_message("user", user_input)
        if thinking_type is None:
            thinking_type = DEFAULT_THINKING_TYPE

        response = self.client.chat.completions.create(
            model=API_CONFIG["model"],
            messages=self.history_messages,
            thinking={"type": thinking_type},
        )

        assistant_response = response.choices[0].message.content
        context = f"{self.name}:{assistant_response}"
        self.add_history_message("assistant", context)

        return assistant_response

    def get_conversation_history(self):
        """获取完整对话历史"""
        return self.history_messages

    def clear_history(self):
        """清空对话历史"""
        self.history_messages = []

    def get_message_count(self):
        """获取消息总数"""
        return len(self.history_messages)

    def skill_vote(self, vote_signal, thinking_type=None):
        """投票能力"""
        self.add_history_message("user", vote_signal)
        if thinking_type is None:
            thinking_type = DEFAULT_THINKING_TYPE

        response = self.client.chat.completions.create(
            model=API_CONFIG["model"],
            messages=self.history_messages,
            thinking={"type": thinking_type},
        )

        assistant_response = response.choices[0].message.content
        vote_target = extract_number_from_string(assistant_response)
        vote_2 = f"{self.name}:{assistant_response}"

        self.add_history_message("assistant", vote_2)

        return assistant_response, vote_target

    def skill_kill(self, kill_signal, thinking_type=None):
        """投票能力"""
        self.add_history_message("user", kill_signal)
        if thinking_type is None:
            thinking_type = DEFAULT_THINKING_TYPE

        response = self.client.chat.completions.create(
            model=API_CONFIG["model"],
            messages=self.history_messages,
            thinking={"type": thinking_type},
        )

        assistant_response = response.choices[0].message.content
        kill_target = extract_kill_from_string(assistant_response)
        kill_vote_2 = f"{self.name}:{assistant_response}"

        self.add_history_message("assistant", kill_vote_2)

        return assistant_response, kill_target


def add_messages_to_all(players, context):
    """将历史信息发送给所有玩家"""
    for player_ in players:
        player_.add_history_message("user", context)


def create_players():
    """创建玩家对象"""
    player1 = player("prophet", "positive", "1号", 1)  # 平民
    player2 = player("civilian", "positive", "2号", 2)  # 平民
    player3 = player("civilian", "positive", "3号", 3)  # 平民
    player4 = player("werewolf", "negative", "4号", 4)  # 狼人
    player5 = player("civilian", "positive", "5号", 5)  # 平民
    player6 = player("civilian", "positive", "6号", 6)  # 平民
    player7 = player("civilian", "positive", "7号", 7)  # 平民
    player8 = player("werewolf", "negative", "8号", 8)  # 平民
    players = [player1, player2, player3, player4, player5, player6, player7, player8]  # 所有玩家
    players_werewolf = []  # 狼人玩家
    for werewolf_player in players:
        if werewolf_player.role == "werewolf":
            players_werewolf.append(werewolf_player)
    return players, players_werewolf


def night_action_phase(players, players_werewolf, round_num):
    print("天黑了")
    print(f"\n--- 第{round_num + 1}轮夜晚 ---")
    context_night = f"天黑了，第{round_num + 1}天夜晚"
    add_messages_to_all(players, context_night)

    for player_ in players:  # 一次性技能判断
        if player_.role == "prophet" and player_.is_alive:
            print("\n预言家请睁眼，请选择要查验的对象\n")
            target_str = player_.get_response("预言家请睁眼，请选择要查验的对象")
            print(f"{player_.name}: {target_str}")
            target_num = extract_number_from_string(target_str)
            for player_role in players:
                if player_role.id == target_num:
                    print(f"你查验的对象{target_num}号的阵营为:{player_role.faction},请闭眼")
                    player_.add_history_message("user",
                                                f"你查验的对象{target_num}号的阵营为:{player_role.faction},请闭眼")

    players_werewolf_num = []
    for player_ in players_werewolf:
        if player_.is_alive:
            players_werewolf_num.append(f"{player_.id}号")
    print(f"狼人请睁眼，剩余的狼人为:{players_werewolf_num}，请交流决定击杀目标")
    add_messages_to_all(players_werewolf,
                        f"狼人请睁眼，剩余的狼人为:{players_werewolf_num}，请交流决定击杀目标")  # 狼人行动开始

    kill_results_list = []  # 用于记录击杀投票结果
    for player_ in players_werewolf:
        if player_.is_alive:
            kill_messages, kill_target = player_.skill_kill("到你发言，决定击杀对象")
            kill_results_list.append(kill_target)
            print(f"{player_.name}:{kill_messages}")
            for other_player in players_werewolf:
                if other_player.name != player_.name:
                    other_player.add_history_message("user", f"{player_.name}:{kill_messages}")

    kill_final_target, kill_vote_num = find_most_frequent_kill(kill_results_list)
    for player_ in players:
        if player_.id == kill_final_target:
            player_.is_alive = False

    print(f"最终决定的击杀对象为:{kill_final_target}号")
    add_messages_to_all(players_werewolf, f"最终决定的击杀对象为:{kill_final_target}号")
    return kill_final_target


def morning_discussion_phase(players, kill_final_target, round_num):
    """处理早上的讨论阶段"""
    print(f"\n--- 第{round_num + 1}轮早上 ---")

    context_morning = f"天亮了，第{round_num + 1}天早上"
    for player_ in players:
        player_.add_history_message("user", context_morning)

    for player_ in players:
        if player_.id == kill_final_target:
            print(f"昨晚上，{kill_final_target}号死了。")
            add_messages_to_all(players, f"昨晚上，{kill_final_target}号死了。")
            if round_num == 0:
                print(f"因为是第一晚上死亡，存在遗言，请{kill_final_target}号发表遗言。")
                add_messages_to_all(players, f"因为是第一晚上死亡，存在遗言，请{kill_final_target}号发表遗言。")
                last_words = player_.get_response(f"因为是第一晚上死亡，存在遗言，请{kill_final_target}号发表遗言。")
                print(f"{player_.name}:{last_words}")
                add_messages_to_all(players, f"{player_.name}:{last_words} \n 遗言结束 \n")
                print("\n遗言结束\n")

    # 早上聊天阶段
    for player_ in players:
        try:
            if not player_.is_alive:
                continue
            else:
                # 获取玩家发言
                response = player_.get_response("\n轮到你发言\n")
                print(f"{player_.id}号: {response}")

                for other_player in players:
                    if other_player.name != player_.name:
                        other_player.add_history_message("user", f"{player_.id}: {response}")

                # 短暂延迟，避免API调用过快
                time.sleep(1)

        except Exception as e:
            print(f"{player_.name} 发言失败: {e}")


def voting_phase(players, round_num):
    """处理投票阶段"""
    print(f"\n--- 第{round_num + 1}轮投票阶段 ---")
    context_vote_signal = f"当天发言结束，请开始第{round_num + 1}天投票"
    vote_results_list = []  # 用于记录投票结果
    vote_record_list = []
    for player_ in players:
        if player_.is_alive:
            vote, vote_record = player_.skill_vote(context_vote_signal)
            vote_results_list.append(vote)
            vote_record_list.append(vote_record)
    print("投票结果 : " + str(vote_record_list))
    # print(vote_results_list)
    return vote_record_list


def process_voting_results(players, players_werewolf, vote_record_list, round_num):
    """处理投票结果"""
    vote_result, vote_count = find_most_frequent_vote(vote_record_list)  # 统计投票结果
    if vote_result == "弃权":
        print("今天无人出局")
        add_messages_to_all(players, "今天无人出局。")
    else:
        add_messages_to_all(players, f"第{round_num + 1}天早上, {vote_result}号获得: {vote_count}票, 被放逐")
        for player_ in players:
            if player_.id == vote_result:
                player_.is_alive = False
                game_flag = game_over(players)  # 判断胜利条件
                if not game_flag:
                    return game_flag
                last_words = player_.get_response("你已死亡， 请发表遗言")
                print(f"{player_.name}: {last_words}")
                # 将玩家的发言添加到其他玩家的历史中
                for other_player in players:
                    if other_player.name != player_.name:
                        other_player.add_history_message("user", f"{player_.name}说: {last_words}")
                # print(player_.get_conversation_history())
    return True


def game_over(players):
    players_good_num = 0
    players_werewolf_num = 0
    for player_ in players:
        if player_.is_alive and player_.faction == 'positive':
            players_good_num += 1
        if player_.is_alive and player_.faction == 'negative':
            players_werewolf_num += 1

    if players_good_num <= players_werewolf_num:
        print("\n游戏结束,坏人胜利！\n")
        return False
    if players_werewolf_num == 0:
        print("\n游戏结束, 好人胜利!\n")
        return False
    return True
